
/*
1. 有大量 IO 任务需要并发运行时，选 async 模型
2. 有部分 IO 任务需要并发运行时，选多线程，如果想要降低线程创建和销毁的开销，可以使用线程池
3. 有大量 CPU 密集任务需要并行运行时，例如并行计算，选多线程模型，且让线程数等于或者稍大于 CPU 核心数
4. 无所谓时，统一选多线程
*/

// use std::thread;
// use std::future::join;
// use core::future::join;

use futures::executor::block_on;

struct Song {
    name: String,
    author: String,
}

async fn learn_song() -> Song {
    Song {
        name: "<My Mother>".to_string(),
        author: "Fred".to_string(),
    }
}

async fn sing_song(song: Song) {
    println!("I will sing a {}'s {}.", song.author, song.name);
}

async fn dance() {
    println!("Be singing and dancing at once.");
}

async fn learn_sing() {
    let s = learn_song().await;
    sing_song(s).await;
}

async fn main_async() {
    let sf = learn_sing();
    let df = dance();

    futures::join!(sf, df);
}

fn main() {
    block_on(main_async());
}

/*
async fn do_something() {
    println!("go go go!");
}

fn main() {
    // println!("Hello, world!");
    let future = do_something();
    block_on(future);
}
*/

/*
// 多线程
fn get_two_sites() {
    // 创建两个新线程执行任务
    let thread_one = thread::spawn(|| download("https://course.rs"));
    let thread_two = thread::spawn(|| download("https://fancy.rs"));

    // 等待两个线程的完成
    thread_one.join().expect("thread one panicked");
    thread_two.join().expect("thread two panicked");
}

// 异步 async
async fn get_two_sites_async() {
    // 创建两个不同的`future`，你可以把`future`理解为未来某个时刻会被执行的计划任务
    // 当两个`future`被同时执行后，它们将并发的去下载目标页面
    let future_one = download_async("https://www.foo.com");
    let future_two = download_async("https://www.bar.com");

    // 同时运行两个`future`，直至完成
    join!(future_one, future_two);
}
*/
